package tk.sunlatus.project.security.decode.impl;

import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

import tk.sunlatus.project.common.constants.SunlatusConstants;
import tk.sunlatus.project.security.decode.Decoder;
import tk.sunlatus.project.security.key.KeyManager;

public class DecoderIDEAImpl implements Decoder {

    private byte[] keyByte = null;

    /**
     * 解密
     * 
     * @param data
     * @return
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     */
    public byte[] decrypt(byte[] data) {
        if (keyByte == null) {
            return null;
        }
        return decrypt(keyByte, data);
    }

    public byte[] decrypt(byte[] keyByte, byte[] data) {
        Key key = KeyManager.bytesToKey(keyByte, false);
        return decrypt(key, data);
    }

    public byte[] decrypt(Key key, byte[] data) {
        try {
            return initCipher(key).doFinal(data);
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (BadPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public byte[] decrypt(byte[] keyByte, String data) {
        Key key = KeyManager.bytesToKey(keyByte);
        return decrypt(key, data);
    }

    public byte[] decrypt(Key key, String data) {
        return decrypt(key, Hex.decode(data.getBytes(SunlatusConstants.EncodeConstant.CHARSET)));
    }

    private Cipher initCipher(Key key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
        Security.addProvider(new BouncyCastleProvider());
        if (key == null) {
            key = KeyManager.bytesToKey(keyByte);
        }
        Cipher cipher = Cipher.getInstance(SunlatusConstants.EncodeConstant.ALGORITHM_IDEA);
        cipher.init(Cipher.DECRYPT_MODE, key);
        return cipher;
    }

    /**
     * @param keyByte
     *            the keyByte to set
     */
    public void setKeyByte(byte[] keyByte) {
        this.keyByte = keyByte;
    }
}
